home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 April: Mac OS SDK / Dev.CD Apr 00 SDK1.toast / Development Kits / Mac OS / Open Transport 1.3 / Open Transport SDK / Open Tpt Client Developer / Samples / Internet / OTMulticastCatchSample.cp < prev    next >
Encoding:
Text File  |  1998-04-30  |  5.4 KB  |  213 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        OTMulticastcatch.cp
  3.  
  4.     Contains:    Sample program to receive UDP/IP multicasts.
  5.  
  6.     Copyright:    © 1993-1996 by Apple Computer, Inc., all rights reserved.
  7.  
  8.     
  9. */
  10.  
  11.  
  12. #include <OpenTptInternet.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <Events.h>
  16. #include <Quickdraw.h>
  17.  
  18.  
  19. /*******************************************************************************
  20. ** Globals
  21. ********************************************************************************/
  22.  
  23. char            gMulticastAddrStr[] = "235.1.2.3";
  24. InetPort        gMulticastPort = 2345;
  25. InetHost        gMulticastHost;
  26. InetAddress        gMulticastAddr;
  27. Boolean            gDataEvent = false;
  28. EndpointRef        gEndpt;
  29. char            gMessage[256];
  30.  
  31. /*******************************************************************************
  32. ** EventHandler
  33. ********************************************************************************/
  34.  
  35. pascal void EventHandler(void*, OTEventCode event, OTResult, void*)
  36. {
  37.     if (event == T_DATA)
  38.         gDataEvent = true;
  39.     return;
  40. }
  41.  
  42.  
  43. /*******************************************************************************
  44. ** SetupMulticast
  45. ********************************************************************************/
  46.  
  47. OSStatus SetupMulticast()
  48. {
  49.     TEndpointInfo    info;
  50.     OSStatus        err = kOTNoError;
  51.     InetAddress        myAddr;
  52.  
  53.     fprintf(stderr, "The program receives multicasts on IPAddr <%s> port <%d>\n", 
  54.         gMulticastAddrStr, gMulticastPort);
  55.     
  56.     do
  57.     {
  58.         //
  59.         //    Get a UDP endpoint which can be used for IP Multicast receives
  60.         //
  61.         
  62.         gEndpt = OTOpenEndpoint(OTCreateConfiguration(kUDPName), 0, &info, &err);
  63.         if ( gEndpt == NULL || err != kOTNoError )
  64.         {
  65.             fprintf(stderr, "ERROR: OpenEndpoint(UDP) failed with error <%d>\n", err);
  66.             break;
  67.         }
  68.         
  69.         //
  70.         //    Set up an Inet Address for the multicast group 
  71.         //    using our multicast address string and defined port number.
  72.         //
  73.         
  74.         OTInetStringToHost(gMulticastAddrStr, &gMulticastHost);
  75.         OTInitInetAddress(&gMulticastAddr, gMulticastPort, gMulticastHost);
  76.     
  77.         //
  78.         //    Do a normal bind to the any IP addr on our system (by entering 0 as 
  79.         //    a wildcard IP address) using the multicast port.
  80.         //    It's OK to use req for both input and output.
  81.         //
  82.         
  83.         OTInitInetAddress(&myAddr, gMulticastPort, 0);
  84.         TBind bindReq;
  85.         bindReq.addr.len = sizeof(myAddr);
  86.         bindReq.addr.maxlen = sizeof(myAddr);
  87.         bindReq.addr.buf = (unsigned char*) &myAddr;
  88.         err = gEndpt->Bind(&bindReq, &bindReq);
  89.         if ( err != kOTNoError )
  90.         {
  91.             fprintf(stderr, "ERROR: Bind() failed with error <%d>\n", err);
  92.             break;
  93.         }
  94.     
  95.         //
  96.         //    Let IP know to listen for this multicast IP address on all interfaces.
  97.         //    
  98.         
  99.         TOptMgmt             optReq;
  100.         UInt8                 optBuffer[ kOTOptionHeaderSize + sizeof(TIPAddMulticast) ];
  101.         TOption*             opt = (TOption*)optBuffer;
  102.         TIPAddMulticast*    addopt = (TIPAddMulticast*)opt->value; 
  103.         
  104.         optReq.flags = T_NEGOTIATE;
  105.         optReq.opt.len = sizeof(optBuffer);
  106.         optReq.opt.buf = (UInt8*) optBuffer;
  107.         
  108.         opt->level = INET_IP;
  109.         opt->name = IP_ADD_MEMBERSHIP;
  110.         opt->len = sizeof(optBuffer);
  111.         
  112.         addopt->multicastGroupAddress = gMulticastHost;
  113.         addopt->interfaceAddress = kOTAnyInetAddress;
  114.         
  115.         err = gEndpt->OptionManagement(&optReq, &optReq);
  116.         if ( err != kOTNoError )
  117.         {
  118.             fprintf(stderr, "ERROR: OTOptionManagement() failed with %d\n", err);
  119.             break;
  120.         }
  121.         
  122.         //
  123.         //    Now install a notifier for and switch to asynchronous mode.
  124.         //
  125.         
  126.         err = gEndpt->InstallNotifier((OTNotifyProcPtr)&EventHandler, 0);
  127.         if ( err != kOTNoError )
  128.         {
  129.             fprintf(stderr, "ERROR: InstallNotifier() failed with error <%d>\n", err);
  130.             break;
  131.         }
  132.         err = gEndpt->SetAsynchronous();
  133.         if ( err != kOTNoError )
  134.         {
  135.             fprintf(stderr, "ERROR: SetAsynchronous() failed with error <%d>\n", err);
  136.             break;
  137.         }
  138.     } while(false);
  139.     return ( err != kOTNoError );
  140. }
  141.  
  142.  
  143. /*******************************************************************************
  144. ** Cleanup
  145. ********************************************************************************/
  146.  
  147. void Cleanup()
  148. {
  149.     gEndpt->Close(); 
  150. }
  151.  
  152.  
  153. /*******************************************************************************
  154. ** RecvLoop
  155. ********************************************************************************/
  156.  
  157. void RecvLoop()
  158. {
  159.     TUnitData    unitdata;
  160.     InetAddress    addr;
  161.     OTFlags        flags;
  162.     char        remoteAddrStr[32];
  163.     char        messageBuf[128];
  164.  
  165.     OTMemzero(messageBuf, sizeof(messageBuf));
  166.     OTMemzero(remoteAddrStr, sizeof(remoteAddrStr));
  167.     while ( !Button() )
  168.     {
  169.         if ( gDataEvent )
  170.         {
  171.             gDataEvent = false;
  172.             unitdata.addr.maxlen = sizeof(addr);
  173.             unitdata.addr.buf = (unsigned char*) &addr;
  174.             unitdata.opt.maxlen = 0;
  175.             unitdata.opt.buf = 0;
  176.             unitdata.udata.maxlen = sizeof(gMessage);
  177.             unitdata.udata.buf = (UInt8*) gMessage;
  178.             gEndpt->RcvUData( &unitdata, &flags);
  179.             OTInetHostToString( addr.fHost, remoteAddrStr);
  180.             fprintf(stderr, "IP multicast from <%s>:%s\n", remoteAddrStr, gMessage);
  181.             OTMemzero(messageBuf, unitdata.udata.len);             
  182.             OTMemzero(remoteAddrStr, sizeof(remoteAddrStr));
  183.         }
  184.     }
  185. }
  186.  
  187.  
  188. /*******************************************************************************
  189. ** Inits
  190. ********************************************************************************/
  191.  
  192. void Inits()
  193. {
  194.     InitGraf(&qd.thePort);
  195.     if ( InitOpenTransport() != kOTNoError )
  196.     {
  197.         fprintf(stderr, "MulticastCatchSample: Could not initialize ASLM\n");
  198.         exit(1);
  199.     }
  200. }
  201.  
  202.  
  203. /*******************************************************************************
  204. ** Main
  205. ********************************************************************************/
  206.  
  207. void main()
  208. {
  209.     Inits();
  210.     if ( SetupMulticast() == kOTNoError )
  211.         RecvLoop();
  212.     Cleanup();
  213. }